import json
from typing import Optional

import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel

from setting import *

app = FastAPI()


class ArticleData(BaseModel):
    id: Optional[int] = None
    article_id: Optional[int] = None
    article_title: Optional[str] = None
    article_content: Optional[str] = None
    article_status: Optional[int] = None
    article_platform: Optional[str] = None
    article_product_id: Optional[str] = None
    article_brand: Optional[str] = None
    article_category: Optional[str] = None
    article_publish_time: Optional[str] = None
    article_update_time: Optional[str] = None
    archive_time: Optional[str] = None


class CategoryData(BaseModel):
    id: Optional[int] = None
    name: Optional[str] = None
    parent_id: Optional[int] = None
    level: Optional[int] = None
    image_url: Optional[str] = None
    sort: Optional[int] = None
    create_time: Optional[str] = None
    update_time: Optional[str] = None


class MappingItem(BaseModel):
    id: Optional[int] = None
    original_name: str
    standard_name: Optional[str] = None


async def get_mapping(table_name: str, original_name: str, error_message: str):
    """
    通用映射查询接口
    Args:
        table_name (str): 表名
        original_name (str): 原始名称
        error_message (str): 未找到时的错误信息
    Returns:
        dict: 包含映射信息的响应
    """
    # 重新连接数据库
    conn.ping(reconnect=True)
    try:
        cursor.execute(f"SELECT id, original_name, standard_name ,multiple_flag,error FROM {table_name} WHERE original_name = %s", (original_name,))

        result = cursor.fetchone()

        #  当品牌映射结果为无时 修改结果为未知品牌
        if result and result[2] == "无":
            result[2] = "未知品牌"

        ############################################### 特殊处理，当进行品牌映射时，若查询后结果为NULL 直接返回原品牌 ###############################################

        if result and table_name == "brand_mapping" and result[2] is None:
            return {
                "status": "success",
                "data": {
                    "id": result[0],
                    "original_name": result[1],
                    "standard_name": result[1]}}

        ##################################################################################################################################################

        # 有结果 并且 multiple_flag ==0 和 error ==0
        if result and result[3] == 0 and result[4] == 0:
            return {
                "status": "success",
                "data": {
                    "id": result[0],
                    "original_name": result[1],
                    "standard_name": result[2]
                }
            }
        else:
            try:
                if not result:
                    # 如果记录不存在，则插入空的新记录 
                    cursor.execute(
                        f"INSERT INTO {table_name} (original_name, standard_name, multiple_flag, error) VALUES (%s, %s, %s, %s)",
                        (original_name, None, 0, 1))
                    conn.commit()
                    return {"status": "error", "message": error_message}

                else:
                    # 如果有记录，则更新error字段 或上 1
                    cursor.execute(
                        f"UPDATE {table_name} SET error = {result[4] | 1} WHERE original_name = %s",
                        (original_name,))
                    conn.commit()
                    return {"status": "error", "message": error_message}

            except Exception as e:
                print(f"Error updating {table_name}: {str(e)}")
                conn.rollback()
    except Exception as e:
        return {"status": "error", "message": str(e)}

@app.post("/category-mapping")
async def get_category_mapping(data: MappingItem):
    return await get_mapping(
        "category_mapping",
        data.original_name,
        "未找到对应的分类映射"
    )


@app.post("/brand-mapping")
async def get_brand_mapping(data: MappingItem):
    return await get_mapping(
        "brand_mapping",
        data.original_name,
        "未找到对应的品牌映射"
    )


# @app.get("/categories/{level}")
# async def get_categories(level: int, parent_id: Optional[int] = None):
#     try:
#         # 重新连接数据库
#         conn.ping(reconnect=True)

#         if level == 1:
#             cursor.execute("SELECT id,name,image_url FROM product_category WHERE level = 1 ORDER BY sort")
#         else:
#             if parent_id is None:
#                 return {"status": "error", "message": "parent_id is required for level > 1"}
#             cursor.execute(
#                 "SELECT id,name,image_url FROM product_category WHERE level = %s AND parent_id = %s ORDER BY sort",
#                 (level, parent_id))

#         categories = cursor.fetchall()
#         # 将结果转换为字典列表
#         categories_list = [
#             {
#                 "id": category[0],
#                 "name": category[1],
#                 "image_url": category[2]
#             }
#             for category in categories
#         ]
#         return {"status": "success", "data": categories_list}
#     except Exception as e:
#         return {"status": "error", "message": str(e)}


@app.get("/categories/{level}")
async def get_categories(level: int, parent_id: Optional[int] = None):
    try:
        # 重新连接数据库
        conn.ping(reconnect=True)

        if level == 1:
            cursor.execute("SELECT id,name,image_url,weight FROM product_category WHERE level = 1  and status='1'  ORDER BY sort")
        else:
            if parent_id is None:
                return {"status": "error", "message": "parent_id is required for level > 1"}
            cursor.execute(
                "SELECT id,name,image_url,weight FROM product_category WHERE level = %s AND parent_id = %s ORDER BY sort",
                (level, parent_id))
        categories = cursor.fetchall()
        
        # 将结果转换为字典列表
        categories_list = [
            {
                "id": category[0],
                "name": category[1],
                "image_url": category[2],
                "weight": category[3]
            }
            for category in categories
        ]
        categories_list.sort(key=lambda x: x["weight"], reverse=True)
        
        return {"status": "success", "data": categories_list}
    except Exception as e:
        return {"status": "error", "message": str(e)}




@app.post("/article/")
async def receive_article(data: ArticleData):
    # 将数据转换为 JSON 字符串并写入日志
    json_data = json.dumps(data.dict(), ensure_ascii=False, indent=2)

    # 判断是否执行成功
    try:
        # 重新连接数据库
        conn.ping(reconnect=True)
        if cursor.execute("INSERT INTO temp_json_data (data) VALUES (%s)", (json_data,)):
            conn.commit()
            return {"status": "success", "message": "Data received and logged."}
        else:
            return {"status": "error", "message": "Failed to log data."}
    except Exception as e:
        # 记录具体错误信息
        error_msg = f"Database error: {str(e)}"
        return {"status": "error", "message": error_msg}


if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=6000)
